// AviFileStm.cpp: implementation of the CAviFileAsf class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "asf_intf.h"
#include "mmsystem.h"
#include "AviFileAsf.h"

//#include <VFW.h>

//#ifdef _DEBUG
//#undef THIS_FILE
//static char THIS_FILE[]=__FILE__;
//#define new DEBUG_NEW
//#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAviFileAsf::CAviFileAsf()
{
	m_bFileOver = FALSE;
	m_bPCMSound = FALSE;
	//m_AudioBuffer.BufferInit(1024*2, 1024);
	memset(&m_AsfFileHead, 0, sizeof(ASF_INFO_S));
	m_width = 0;
	m_height = 0;
}

CAviFileAsf::~CAviFileAsf()
{
	//m_AudioBuffer.BufferClear();
	//if (m_AsfFile.IsOpened() == TRUE)
	//{
	//	m_AsfFile.CloseFile();
	//}
}

//---------------------------------------------------------------------
//说明：取得帧率等信息，同时返回转换后的文件个数，在打开文件后调用
//参数：无
//返回：成功返回TRUE，失败返回FALSE
//---------------------------------------------------------------------
BOOL CAviFileAsf::GetInfo()
{
	if (!GetAsfFileInfo(&m_AsfFileHead))
		return FALSE;

	int iFileLen = m_strSFileName.size();
//	if(iFileLen < 17)
//	{
//		return FALSE;
//	}

	if (m_AsfFileHead.struVStream.u32avgBitRate != 0)
	{
		// N/P
		if (m_AsfFileHead.struVStream.u32NTSC == 1)
			m_iTvSystem[0] = 'N';
		else
			m_iTvSystem[0] = 'P';

		// D1, HD1, CIF, QCIF
		m_width = m_AsfFileHead.struVStream.u32BiWidth;
		m_height = m_AsfFileHead.struVStream.u32BiHeight;

		// FrameRate
		m_iFrameRate[0] = m_AsfFileHead.struVStream.u32samplePerSec;
		if (m_iFrameRate[0] == 0)
			m_iFrameRate[0] = m_AsfFileHead.struVStream.u32NTSC ? 30:25;
		return TRUE;
	}

	m_iFileNum = 1;
	m_iTvSystem[0] = m_strSFileName.at(iFileLen - 10);	// N/P
	m_iQuality[0] = m_strSFileName.at(iFileLen - 9);	// 1-D1，2-HD1，3-CIF，4-QCIF
	m_iFrameRate[0] = m_strSFileName.at(iFileLen - 6);	// 0x30+framerate 0x30+7+framefate

	if (m_iTvSystem[0] != 'N' && m_iTvSystem[0] != 'P')
		return FALSE;
	if (m_iQuality[0] < '1' || m_iQuality[0] > '4')
		return FALSE;
	if (m_iFrameRate[0] >= '1' && m_iFrameRate[0] <= '9')
	{
		m_iFrameRate[0] -= 0x30;
		return TRUE;
	}
	else if (m_iFrameRate[0] >= 'A' && m_iFrameRate[0] <= 'U')
	{
		m_iFrameRate[0] -= 0x37;
		return TRUE;
	}
	else
		return FALSE;

	return TRUE;
}


//---------------------------------------------------------------------
//说明：修改文件头的信息，在创建完avi(CreateAviHeader)后调用
//参数：[in]header_tb1:头数据
//		[in]iLen:数据长度
//		[in]iChID:通道ID，0-3
//返回：成功返回TRUE，失败返回FALSE
//---------------------------------------------------------------------
BOOL CAviFileAsf::ModifyHeader(unsigned char* header_tb1, int iSize, int iChID)
{
	int iWidth = 704;
	int iHeight = 480;
	if (m_height == 0 || m_width == 0)
	{
		switch (m_iTvSystem[iChID])
		{
			case 'N':
				switch(m_iQuality[iChID])
				{
				case '1':
					iWidth = 704;
					iHeight = 480;
					break;
				case '2':
					iWidth = 704;
					iHeight = 240;
					break;
				case '3':
					iWidth = 352;
					iHeight = 240;
					break;
				case '4':
					iWidth = 176;
					iHeight = 120;
					break;
				case '5':
					iWidth = 1920;
					iHeight = 1080;
					break;
				}
				break;
			case 'P':
				switch(m_iQuality[iChID])
				{
				case '1':
					iWidth = 704;
					iHeight = 576;
					break;
				case '2':
					iWidth = 704;
					iHeight = 288;
					break;
				case '3':
					iWidth = 352;
					iHeight = 288;
					break;
				case '4':
					iWidth = 176;
					iHeight = 144;
					break;
				case '5':
					iWidth = 1920;
					iHeight = 1080;
					break;
				}
				break;
		}
	}
	else
	{
		iWidth = m_width;
		iHeight = m_height;
	}

	int iFrameSpace = 1000000/m_iFrameRate[0];

	header_tb1[0xb0] = iWidth&0xff; // 0xC0	//BITMAPINFOHEADER	biWidth
	header_tb1[0xb1] = iWidth>>8&0xff; // 0x02
	header_tb1[0xb4] = iHeight&0xff; // 0xE0	//BITMAPINFOHEADER	biHeight
	header_tb1[0xb5] = iHeight>>8&0xff; // 0x01
	
	header_tb1[0xa0] = header_tb1[0xb0];
	header_tb1[0xa1] = header_tb1[0xb1];
	header_tb1[0xa2] = header_tb1[0xb4];
	header_tb1[0xa3] = header_tb1[0xb5];
	
	header_tb1[0x40] = header_tb1[0xb0];
	header_tb1[0x41] = header_tb1[0xb1];
	header_tb1[0x44] = header_tb1[0xb4];
	header_tb1[0x45] = header_tb1[0xb5];

	header_tb1[0xfc]=0x02;			//dwScale;
	header_tb1[0xfd]=0x00;
	header_tb1[0xfe]=0x00;
	header_tb1[0xff]=0x00;
	header_tb1[0x100]=0x80;	// 0x40	// 采样率
	header_tb1[0x101]=0x3e; // 0x1f
	header_tb1[0x102]=0x00;	// 0x00
	header_tb1[0x103]=0x00; // 0x00

	header_tb1[0x114]=0x02; // 采样大小
	
	WAVEFORMATEX AudioHeader = {0};
	AudioHeader.wFormatTag = WAVE_FORMAT_PCM;
	AudioHeader.nChannels = 1;
	AudioHeader.nSamplesPerSec = 8000;
	AudioHeader.nAvgBytesPerSec = AudioHeader.nSamplesPerSec * AudioHeader.nChannels * 2;
	AudioHeader.nBlockAlign = AudioHeader.nChannels * 2;
	AudioHeader.wBitsPerSample = 16;
	AudioHeader.cbSize = 18;
	memcpy(&header_tb1[0x128], &AudioHeader, sizeof(WAVEFORMATEX));

	header_tb1[0x38] = 2;	 // 流的个数
			
	header_tb1[0x20] = iFrameSpace&0xff; // 0x35	33333		//dwMicroSecPerFrame; // 视频帧间隔时间（以毫秒为单位）
	header_tb1[0x21] = iFrameSpace>>8&0xff; // 0x82
	header_tb1[0x22] = iFrameSpace>>16&0xff;
	header_tb1[0x23] = iFrameSpace>>24&0xff;
	header_tb1[0x80] = header_tb1[0x20]; // 0x35 0x76	33333	//dwInitialFrames; // 为交互格式指定初始帧数
	header_tb1[0x81] = header_tb1[0x21]; // 0x82 0x42
	header_tb1[0x82] = header_tb1[0x22]; //
	header_tb1[0x83] = header_tb1[0x23]; // 
	header_tb1[0x84] = 0x40; // 0x40	1000000		//dwScale; // 这个流使用的时间尺度
	header_tb1[0x85] = 0x42; // 0x42
	header_tb1[0x86] = 0x0f; // 0x0f
	header_tb1[0x87] = 0x00; // 

	return TRUE;
}

//---------------------------------------------------------------------
//说明：转换音频数据
//参数：[in]chunk:原始的音频数据
//		[in]chunkLength:原始音频数据大小
//		[in]target:存放转换后的音频数据
//		[in]iTarget:target文件的大小,调用时传递数据缓冲的原始大小
//			调用后返回实际的大小
//返回：成功返回TRUE，失败返回FALSE
//---------------------------------------------------------------------
BOOL CAviFileAsf::DecoderAudioData(unsigned char *chunk, int chunkLength, unsigned char* target, int& iTarget)
{
	//m_AudioBuffer.WriteG726AFrame((char *)chunk, chunkLength, (char *)target, &iTarget);

	return TRUE;
}

//---------------------------------------------------------------------
//说明：从文件中读取数据
//参数：无
//返回：成功返回TRUE，失败返回FALSE
//---------------------------------------------------------------------
BOOL CAviFileAsf::ReadFileData()
{
	//if (m_AsfFile.IsOpened() == FALSE)
	//{
	//	int iCntWnd = 0, iCh_id = 0;
	//	if(!m_AsfFile.OpenFileEx((char *)m_strSFileName.c_str(), iCntWnd, &iCh_id))
	//		return FALSE;
	//}

	//int BufSize = 0;
	//int FrameType = 0;
	//LONGLONG Framestamp = 0;
	//if (m_AsfFile.ReadFileData((char *)(m_szBuffer+m_lDataSize), &BufSize) == TRUE)
	//{
	//	FrameType = *(int *)(m_szBuffer+m_lDataSize);
	//	if (FrameType != 0x63643939)// && FrameType != 0x63643030)// && FrameType != 0x62773130)
	//		m_lDataSize += BufSize;
	//	
	//	if (m_bFileOver == FALSE && m_AsfFile.m_TotalSecond == m_AsfFile.m_StartTime.Pts)
	//	{
	//		m_bFileOver = TRUE;
	//	}
	//}
	//else
	//{
	//	return FALSE;
	//}

	return TRUE;
}

//---------------------------------------------------------------------
//说明：取得P帧的偏移长度，P帧中可能存在一定的无效数据，因此需要删除
//参数：[in]stream:帧数据
//		[in]iLen:数据长度
//返回：返回P帧的偏移长度
//调用：ChangeFile()中调用
//---------------------------------------------------------------------
int	CAviFileAsf::GetPFrameOffset(unsigned char *stream, int iLen)
{
	return 8;
}

//---------------------------------------------------------------------
//说明：取得P帧的偏移长度，P帧中可能存在一定的无效数据，因此需要删除
//参数：[in]stream:帧数据
//		[in]iLen:数据长度
//返回：返回P帧的偏移长度
//调用：ChangeFile()中调用
//---------------------------------------------------------------------
int	CAviFileAsf::GetAFrameOffset(unsigned char *stream, int iLen)
{
	return 8;
}

// 获取Asf文件头信息结构体。
BOOL CAviFileAsf::GetAsfFileInfo(ASF_INFO_S *struAsfInfo)
{
	//CFBAsfFile TmpAsf;
	//int iCntWnd = 0, iCh_id = 0;
	//if(!TmpAsf.OpenFileEx((char *)m_strSFileName.c_str(), iCntWnd, &iCh_id))
	//	return FALSE;
	//*struAsfInfo = TmpAsf.GetAsfFileInfo();
	//if (TmpAsf.IsOpened() == TRUE)
	//	TmpAsf.CloseFile();

	return TRUE;
}